Outputs

Archivos csv

Los archivos separados por comas son uno de los formatos más utilizados para compartir información. En R podemos crear estos tipos de archivos con la función: write.csv().

Siguiendo con el ejemplo que estamos trabajando, vamos a guardar la variable estimacion en nuestros equipos. Para ello empleamos los siguientes comandos:

write.csv(estimacion, file = "DR/acciones/descriptivas.csv", 
          row.names = FALSE
          )

estimacion debe existir en el ambiente de trabajo y file es la ruta donde deseamos guardar el archivo, note que incluye el nombre y la extención.

Imágenes

Los plots se pueden guardar en diferentes formatos: png, jpg, svg, bmp, tiff entre otras. Esta acción se puede llevar acabo vía interfaz o mediante líneas de comando. Esta última tiene la ventaja de automatizar el procedimiento.

El siguiente código guarda una imágen en formato svg.

# Se abre el dispositivo (svg).
svg(filename = "plot/probabilidad.svg")

# Se realiza el gráfico.
plot(estimacion[, 3], type = "l")

# Se cierra el dispositivo.
dev.off()

La función graficos_precio() la podemos modificar para que guarde todos los gráficos en el siguiente directorio: plot/acciones/.

graficos_precio <- function(x) {
  nombre <- colnames(x)[2]
  nombre <- gsub(pattern = ".Open", replacement = "", nombre)
  ruta <- paste0("plot/acciones/", nombre, ".svg")
  svg(ruta)
  plot(x[, 1], x[, 4], type = "l", main = nombre, 
       ylab = "Precio", xlab = "Año")
  grid(30, 30)
  dev.off()
  return(NULL)
}

Introdución a Tidyverse

Tidyverse es un conjunto de paquetes para realizar ciencia de datos. Estos paquetes comparten un mismo marco o gramática que crean una sinergía en el análisis. Varios de estos fueron escritos por Hadley Wickham en RStudio.

Estos paquetes permiten limpiar, describir, modelar y graficar datos de manera sencilla. Entre ellos se destacan:

  • ggplot2: Este paquete permite realizar gráficos y esta básado en The Grammar of Graphics de Leland Wilkinson.
  • dplyr: Este paquete permite manipular datos a partir de una gramatica basada en 5 verbos.
  • tidyr: Esta colección de funciones ayudan a organizar datos en una forma adecuada para realizar anális de datos.

Paquetes recomendados

Estos paquetes pueden ser instalados mediente el siguiente comando:

install.packages("tidyverse")

El comando anterior solo se requiere ejecutar una vez. Luego de instalados podemos cargar las funciones con la siguiente línea de código:

library("tidyverse")

La línea anterior se debe ejecutar cada vez que se inicie una nueva sesión en R.

ggplot2

Este paquete es utilizado para realizar gráficos estadísticos y esta basado en la grámatica desarrollada por Wilkinson (1999). Esta gramática responde a la pregunga ¿Que es un gráfico estadístico? (Wickham 2010).

Estos gráficos son el resultado de asignar atributos estéticos (colores, formas, tamaños) a un conjunto de datos. ggplot2 permite incorporar un conjunto de componentes independientes en un mismo ‘‘layout’’ para crear visualizaciones robustas.

Extenciones se han realizado para crear arte algoritmico. Algunos ejemplos: Antonio Sánchez, Thomas Lin Pedersen, aRtsy, R Image Art, Getting Started with Generative Art in R.

Elementos básicos

Para crear un gráfico con ggplot2 se requiere de los siguientes elementos:

  • Datos: Deben estar en forma de data.frame o data.table.
  • Propiedades estéticas: Estas se definen con la función aes() y asignan los atributos que se pueden percibir como: color, tamaño, posicion, formas.
  • Geométrias: Estas definen el tipo de gráfico: puntos, lineas, barras, boxplot, etc.
  • Facetas: Estas permiten dividir el

Para una mayor comprensión consultar Wickham (2010).

Ejemplo

En este ejemplo vamos a trabajar con las medidas descriptivas que se obtuvieron de las acciones.

library(ggplot2)
library(readr)
 datos_acciones <- read_csv(
   file = "../Datos/Fin_Semana_2/descriptivas.csv"
   )

head(datos_acciones[1:5], 3)
## # A tibble: 3 x 5
##   rendimientos riesgo probabilidad intercepto pendiente
##          <dbl>  <dbl>        <dbl>      <dbl>     <dbl>
## 1     0.000545 0.0180        0.517      -152.    0.0117
## 2     0.00119  0.0292        0.512      -257.    0.0176
## 3     0.000449 0.0184        0.517      -543.    0.0403

ggplot(data = datos_acciones, aes(riesgo, rendimientos))

ggplot(data = datos_acciones, aes(riesgo, rendimientos)) + 
  geom_point()

ggplot(data = datos_acciones, aes(riesgo, rendimientos)) + 
  geom_point(colour = "salmon")

ggplot(data = datos_acciones, aes(riesgo, rendimientos)) + 
  geom_point(colour = "salmon") + theme_linedraw()

ggplot(data = datos_acciones, aes(riesgo, rendimientos)) + 
  geom_point(shape = 21, colour = "black", fill = "salmon") + 
  theme_linedraw()

ggplot(data = datos_acciones, 
    aes(x = riesgo, y = rendimientos, fill = color)
       ) +  geom_point(shape = 21) + theme_linedraw()

ggplot(data = datos_acciones, 
    aes(x = riesgo, y = rendimientos, colour = color)
       ) + geom_point() + theme_linedraw() +
  scale_color_manual(values = c("darkgreen", "red"))

ggplot(data = datos_acciones, 
    aes(x = riesgo, y = rendimientos, colour = color)
       ) + geom_point(alpha = 0.4) + theme_linedraw() +
  scale_color_manual(values = c("darkgreen", "red"))

ggplot(data = datos_acciones, 
       aes(x = riesgo, y = rendimientos, 
           colour = color, size = abs(pendiente))
       ) +  geom_point(alpha = 0.3) + theme_linedraw() +
  scale_color_manual(values = c("darkgreen", "red"))

ggplot(data = datos_acciones, 
       aes(x = riesgo, y = rendimientos, 
           colour = color, size = abs(pendiente))
       ) +  geom_point(alpha = 0.3) + theme_linedraw() +
  scale_color_manual(values = c("darkgreen", "red")) + 
  ggtitle(label = "Riesgo vs Retorno", subtitle = "Renta variable") + 
  ylab(label = expression(mu)) + xlab(expression(sigma))

Por último se puede modifiar las siguientes caracteristícas:

  • Títulos: al gráfico, a los ejes y eliminar las leyendas.

  • Agregar una línea línea a \(45^\circ\) y otra horizontal en cero, se debe modificar los límites en el eje x con la función xlim.

 ggplot(data = datos_acciones, 
       aes(x = riesgo, y = rendimientos, 
           colour = color, size = abs(pendiente))
       ) +  geom_point(alpha = 0.3) + theme_linedraw() +
  scale_color_manual(values = c("navy", "salmon")) + 
  ggtitle(label = "Riesgo vs Retorno", subtitle = "Renta variable") + 
  ylab(label = expression(mu)) + xlab(expression(sigma)) + 
  xlim(c(0, 0.04)) +  geom_hline(yintercept = 0, colour = "red") + 
  geom_abline(slope = 1, intercept = 0, color = "purple") + 
  theme(legend.position = "none")

Optimizar el portafolio (un gran paréntesis)

Ya que tenemos el gráfico de riegos vs retorno, podemos proceder a optimizar un portafolio basados en el trabajo desarrollado por Markowitz (1952).

\[\max z= \lambda\sum_{i = 1}^{n} \mu^tx_{i} - (1-\lambda)\sum_{j = 1}^{n}\sum_{i = 1}^{n}x_{i}x_{j}\sigma_{i,j} \\ \sum_{i=1}^{n} x_{i} = 1 \\ x_{i} \ge 0 \\ \lambda \in [0, 1] \]

El modelo anterior se puede expresar de forma matricial como:

\[ \max z = \lambda \mu^tx - (1-\lambda)x^t\Sigma x \\ \sum_{i=1}^{n} x = 1 \\ x \ge 0 \\ \lambda \in [0, 1] \]

\(\mu\) es el promedio de los rendimientos. \(\Sigma\) es la matriz de varianzas y covarianzas de los rendimientos. \(x\) es la variable de decisión que indica la proporción a invertir en cada activo.

Pasos para aplicar el modelo.

  • Se necesitan los rendimientos de los activos \(ln(\frac{p_{t}}{p_{t-1}})\) en una matriz de nxm.

  • Se calculan los promedios de los rendimientos.

  • Calcular la matriz de varianzas y covarianzas. Para esto los activos deben tener la misma cantidad de observaciones.

  • Se requiere de una herramienta para modelar y resolver el problema. Instalar el paquete CVXR

install.packages("CVXR")

CVXR

Tips para trabajar con el paquete:

  • Las variables se declaran con la función Variable(). Es un vector columna.
  • La forma cuadrática con la función quad_form().
  • Las restricciones se pueden crear como una lista().
  • El problema Problem(). Importante indicar si es de maximización o minimización.
  • Se resuelve con solve()

dplyr

dplyr implementa una gramátia para la manipulación de datos. Hay 5 verbos fundamentales:

  • select(): Selecciona variables de acuerdo a su nombre.
  • filter(): Selecciona elementos de la tabla dependiendo de condiciones.
  • mutate(): Crea nuevas columnas a la tabla.
  • summarise(): Agrega valores.
  • arrange(): Cambia el orden de las filas.

Otras funciones utiles son:

  • group_by(): Agrupar por variables.
  • relocate(): Cambia el orden de las columnas.

Ejemplo dplyr

select()

library(dplyr)
datos_acciones %>% select(1:2) %>% head(10)
## # A tibble: 10 x 2
##    rendimientos riesgo
##           <dbl>  <dbl>
##  1     0.000545 0.0180
##  2     0.00119  0.0292
##  3     0.000449 0.0184
##  4     0.000850 0.0160
##  5     0.000805 0.0163
##  6     0.000615 0.0137
##  7     0.00152  0.0293
##  8     0.000388 0.0114
##  9     0.000642 0.0135
## 10     0.000772 0.0174

Seleccionar las columnas 1, 4 y 7.

datos_acciones %>% select(c(1, 4, 7)) %>% head(10)
## # A tibble: 10 x 3
##    rendimientos intercepto titulo
##           <dbl>      <dbl> <chr> 
##  1     0.000545      -152. A     
##  2     0.00119       -257. AAL   
##  3     0.000449      -543. AAP   
##  4     0.000850      -135. AAPL  
##  5     0.000805      -265. ABBV  
##  6     0.000615      -363. ABC   
##  7     0.00152       -769. ABMD  
##  8     0.000388      -122. ABT   
##  9     0.000642      -447. ACN   
## 10     0.000772      -605. ADBE

Se pueden seleccionar con los nombres de las variables.

datos_acciones %>% select(c("riesgo", "intercepto", "pendiente")) %>% 
  head(10)
## # A tibble: 10 x 3
##    riesgo intercepto pendiente
##     <dbl>      <dbl>     <dbl>
##  1 0.0180      -152.   0.0117 
##  2 0.0292      -257.   0.0176 
##  3 0.0184      -543.   0.0403 
##  4 0.0160      -135.   0.00973
##  5 0.0163      -265.   0.0195 
##  6 0.0137      -363.   0.0265 
##  7 0.0293      -769.   0.0510 
##  8 0.0114      -122.   0.00982
##  9 0.0135      -447.   0.0329 
## 10 0.0174      -605.   0.0417

filter()

datos_acciones %>% filter(probabilidad < 0.5) %>% 
  head(10)
## # A tibble: 10 x 7
##    rendimientos riesgo probabilidad intercepto  pendiente color titulo
##           <dbl>  <dbl>        <dbl>      <dbl>      <dbl> <chr> <chr> 
##  1   -0.000116  0.0173       0.499      13.3   -0.0000820 red   AES   
##  2    0.000301  0.0126       0.0911    -19.5    0.00180   navy  AMCR  
##  3    0.0000289 0.0354       0.485      -0.605  0.000397  navy  AMD   
##  4   -0.000457  0.0215       0.490     471.    -0.0245    red   APA   
##  5    0.000314  0.0217       0.497     -49.5    0.00400   navy  BAC   
##  6   -0.000132  0.0238       0.493      62.3   -0.000654  red   BKR   
##  7    0.000503  0.0183       0.492    -116.     0.00802   navy  BSX   
##  8    0.000450  0.0240       0.481     -66.1    0.00555   navy  COG   
##  9    0.000172  0.0175       0.499     -10.8    0.00243   navy  DISCA 
## 10   -0.000306  0.0225       0.490     278.    -0.0138    red   DVN

Varias codiciones se pueden realizar sobre la misma o diferente variable. Por defecto se interpreta como un \(\&\).

datos_acciones %>% filter(probabilidad < 0.5, pendiente < 0) %>% 
  head(10)
## # A tibble: 10 x 7
##    rendimientos riesgo probabilidad intercepto  pendiente color titulo
##           <dbl>  <dbl>        <dbl>      <dbl>      <dbl> <chr> <chr> 
##  1   -0.000116  0.0173        0.499       13.3 -0.0000820 red   AES   
##  2   -0.000457  0.0215        0.490      471.  -0.0245    red   APA   
##  3   -0.000132  0.0238        0.493       62.3 -0.000654  red   BKR   
##  4   -0.000306  0.0225        0.490      278.  -0.0138    red   DVN   
##  5   -0.000107  0.0125        0.498       83.3 -0.00296   red   EXC   
##  6   -0.000392  0.0313        0.490      253.  -0.0140    red   FCX   
##  7   -0.000211  0.0130        0.493      104.  -0.00419   red   FE    
##  8    0.0000277 0.0212        0.494       78.0 -0.00299   red   FTI   
##  9   -0.000158  0.0226        0.490       49.9 -0.00153   red   HWM   
## 10   -0.000313  0.0180        0.475      129.  -0.00609   red   KMI

¿Sí quiero un O?

datos_acciones %>% filter(probabilidad < 0.4  | probabilidad > 0.55) %>% 
  select(probabilidad, titulo)
## # A tibble: 5 x 2
##   probabilidad titulo
##          <dbl> <chr> 
## 1       0.0911 AMCR  
## 2       0.559  DPZ   
## 3       0.554  FISV  
## 4       0.594  IR    
## 5       0.589  LW

Note que no se separa con coma ,.

mutate()

datos_acciones %>%  mutate(datos_acciones, coef_var = rendimientos / riesgo) %>% 
  select(6:8)
## # A tibble: 495 x 3
##    color titulo coef_var
##    <chr> <chr>     <dbl>
##  1 navy  A        0.0303
##  2 navy  AAL      0.0406
##  3 navy  AAP      0.0244
##  4 navy  AAPL     0.0533
##  5 navy  ABBV     0.0494
##  6 navy  ABC      0.0450
##  7 navy  ABMD     0.0521
##  8 navy  ABT      0.0341
##  9 navy  ACN      0.0475
## 10 navy  ADBE     0.0444
## # … with 485 more rows

relocate()

Cambiamos el roden de las variables.

datos_acciones %>% relocate(titulo, .before = rendimientos) %>% 
  select(1:5) 
## # A tibble: 495 x 5
##    titulo rendimientos riesgo probabilidad intercepto
##    <chr>         <dbl>  <dbl>        <dbl>      <dbl>
##  1 A          0.000545 0.0180        0.517      -152.
##  2 AAL        0.00119  0.0292        0.512      -257.
##  3 AAP        0.000449 0.0184        0.517      -543.
##  4 AAPL       0.000850 0.0160        0.524      -135.
##  5 ABBV       0.000805 0.0163        0.535      -265.
##  6 ABC        0.000615 0.0137        0.531      -363.
##  7 ABMD       0.00152  0.0293        0.525      -769.
##  8 ABT        0.000388 0.0114        0.510      -122.
##  9 ACN        0.000642 0.0135        0.532      -447.
## 10 ADBE       0.000772 0.0174        0.525      -605.
## # … with 485 more rows

arrange()

 datos_acciones %>% arrange((rendimientos)) %>% 
  select(1:5)
## # A tibble: 495 x 5
##    rendimientos riesgo probabilidad intercepto pendiente
##           <dbl>  <dbl>        <dbl>      <dbl>     <dbl>
##  1    -0.00253  0.0295        0.436      835.   -0.0471 
##  2    -0.000600 0.0347        0.493      475.   -0.0266 
##  3    -0.000561 0.0371        0.474      -19.7   0.00191
##  4    -0.000457 0.0215        0.490      471.   -0.0245 
##  5    -0.000436 0.0219        0.489      294.   -0.0154 
##  6    -0.000392 0.0313        0.490      253.   -0.0140 
##  7    -0.000391 0.0165        0.507      129.   -0.00594
##  8    -0.000313 0.0180        0.475      129.   -0.00609
##  9    -0.000306 0.0225        0.490      278.   -0.0138 
## 10    -0.000211 0.0130        0.493      104.   -0.00419
## # … with 485 more rows

 datos_acciones %>% arrange(desc(rendimientos)) %>% 
  select(1:5)
## # A tibble: 495 x 5
##    rendimientos riesgo probabilidad intercepto pendiente
##           <dbl>  <dbl>        <dbl>      <dbl>     <dbl>
##  1      0.00297 0.0208        0.594      -891.    0.0526
##  2      0.00218 0.0115        0.589      -814.    0.0495
##  3      0.00177 0.0277        0.544      -719.    0.0451
##  4      0.00162 0.0271        0.548     -1438.    0.0909
##  5      0.00160 0.0342        0.504      -806.    0.0541
##  6      0.00153 0.0179        0.559      -973.    0.0655
##  7      0.00152 0.0293        0.525      -769.    0.0510
##  8      0.00151 0.0244        0.543      -628.    0.0421
##  9      0.00141 0.0292        0.534      -560.    0.0388
## 10      0.00136 0.0318        0.513      -371.    0.0248
## # … with 485 more rows

summarise()

Esta función nos permite agregar la información (medias desviaciones, máximos, mínimos etc).

 datos_acciones %>% summarise(
   max_ren = max(rendimientos), min_ren = min(rendimientos),
   max_riesgo = max(riesgo), min_riesgo = min(riesgo)
   )
## # A tibble: 1 x 4
##   max_ren  min_ren max_riesgo min_riesgo
##     <dbl>    <dbl>      <dbl>      <dbl>
## 1 0.00297 -0.00253     0.0371    0.00860

Los ‘‘verbos’’ anteriores se pueden mezclar entre ellos y con la función group_by podemos realizar operaciones más complejas.

Ejemplo: Rendimientos con dplyr

 library(readr)
 library(dplyr)
 acciones_todas <- read_csv(
   file = "../Datos/Fin_Semana_2/acciones.csv", 
   col_names = TRUE, col_types = list("c", "D", "d")
   )
 head(acciones_todas)
## # A tibble: 6 x 3
##   Activo Fecha      Precio
##   <chr>  <date>      <dbl>
## 1 A      2010-01-04   22.4
## 2 A      2010-01-05   22.1
## 3 A      2010-01-06   22.1
## 4 A      2010-01-07   22.0
## 5 A      2010-01-08   22.0
## 6 A      2010-01-11   22.0

Antes, vamos a ordenarlos de forma descendente por fecha.

acciones_todas %>% arrange(desc(Fecha))
## # A tibble: 959,154 x 3
##    Activo Fecha      Precio
##    <chr>  <date>      <dbl>
##  1 A      2017-12-29   67.0
##  2 AAL    2017-12-29   52.0
##  3 AAP    2017-12-29   99.7
##  4 AAPL   2017-12-29   42.3
##  5 ABBV   2017-12-29   96.7
##  6 ABC    2017-12-29   91.8
##  7 ABMD   2017-12-29  187. 
##  8 ABT    2017-12-29   57.1
##  9 ACN    2017-12-29  153. 
## 10 ADBE   2017-12-29  175. 
## # … with 959,144 more rows

\Oo/

Con la función group_by() se pueden ordenar agrupando por activo.

  acciones_todas <- acciones_todas %>% group_by(Activo) %>%                     
   arrange(desc(Fecha), .by_group = TRUE)
  head(acciones_todas, 7)
## # A tibble: 7 x 3
## # Groups:   Activo [1]
##   Activo Fecha      Precio
##   <chr>  <date>      <dbl>
## 1 A      2017-12-29   67.0
## 2 A      2017-12-28   67.4
## 3 A      2017-12-27   67.3
## 4 A      2017-12-26   67.2
## 5 A      2017-12-22   67.3
## 6 A      2017-12-21   67.5
## 7 A      2017-12-20   67.4

Podemos proceder a calcular los rendimientso

  acciones_todas %>% mutate(
    rendimientos = log(Precio/lead(Precio))
  )
## # A tibble: 959,154 x 4
## # Groups:   Activo [495]
##    Activo Fecha      Precio rendimientos
##    <chr>  <date>      <dbl>        <dbl>
##  1 A      2017-12-29   67.0    -0.00714 
##  2 A      2017-12-28   67.4     0.00223 
##  3 A      2017-12-27   67.3     0.000743
##  4 A      2017-12-26   67.2    -0.00149 
##  5 A      2017-12-22   67.3    -0.00252 
##  6 A      2017-12-21   67.5     0.00178 
##  7 A      2017-12-20   67.4    -0.00518 
##  8 A      2017-12-19   67.8     0.00133 
##  9 A      2017-12-18   67.7     0.000739
## 10 A      2017-12-15   67.6     0.0164  
## # … with 959,144 more rows

Calculemos el rendimiento promedio y la desviación

   acciones_todas %>% mutate(
    rendimientos = log(Precio/lead(Precio))) %>% 
      summarise(Promedio = mean(rendimientos,  na.rm= TRUE),
                Desviacion = sd(rendimientos, na.rm = TRUE)
                )
## # A tibble: 495 x 3
##    Activo Promedio Desviacion
##    <chr>     <dbl>      <dbl>
##  1 A      0.000545     0.0180
##  2 AAL    0.00119      0.0292
##  3 AAP    0.000449     0.0184
##  4 AAPL   0.000850     0.0160
##  5 ABBV   0.000805     0.0163
##  6 ABC    0.000615     0.0137
##  7 ABMD   0.00152      0.0293
##  8 ABT    0.000388     0.0114
##  9 ACN    0.000642     0.0135
## 10 ADBE   0.000772     0.0174
## # … with 485 more rows

Se puede realizar el gráfico directamente.

    acciones_todas %>% mutate(
    rendimientos = log(Precio/lead(Precio))) %>% 
      summarise(Promedio = mean(rendimientos,  na.rm= TRUE),
                Desviacion = sd(rendimientos, na.rm = TRUE)) %>% 
   ggplot(aes(Desviacion, Promedio)) + geom_point()

Ejercicio: datos irradiación

El ejercicio consiste en realizar una análisis descriptivo de los datos irradiación que se encuentran en la carpeta: Datos/Fin_Semana_2/irradiation_profiles.

Actividades

  • Leer los datos y crear un solo objeto con la siguiente estructura:
## # A tibble: 3 x 3
##     dia minuto irradiacion
##   <dbl>  <int>       <dbl>
## 1     1      1           0
## 2     1      2           0
## 3     1      3           0

  • Realizar un gráfico que perminta observar los perfiles para cada día

PCA en R

Estructuras de control

LAS estructuras de control que permiten escoger la “dirección” o la cantidad de veces que un conjunto de instrucciones se ejecutan dependiendo de unos parámetros establecidos y unas variables que están siendo operadas. Las más comunes son: (Wickham 2015)

  • if

  • else if

  • else

  • for

  • while

Estructura if

El if nos permite decidir sobre una ruta de acción partiendo de unas condiciones iniciales y una prueba lógica que marca el camino a seguir.

Ejemplo:

Suponga que usted desea adquirir un crédito de libre inversión, de manera que se dirige a diferentes entidades bancarias para realizar la cotización. Usted lo ha reflexionado y la entidad ha escoger será aquella que ofrezca una tasa inferior al \(22\%\) efectiva anual.

Al conjunto de reglas que se deben seguir para escribir correctamente en un lenguaje de programación se le denomina Sintaxis. La forma adecuada de escribir un if en R es la siguiente.

Sintaxis

if (prueba lógica) {
  Sentencia 1
  Sentencia N
}

Código

i <- 0.28
if(i < 0.22){
  print("Realizar el préstamo")
}

Dos observaciones importantes a tener en cuenta:

  • Una prueba lógica sólo tiene dos resultados: Verdadero y Falso.
  • La sentencia solo se ejecuta en caso de que sea verdadera.

Else if

Volviendo a nuestro ejemplo. Suponga que luego de investigar un poco en internet usted decide que si la tasa es menor a \(24 \%\) su decisión es: “Lo voy a pensar”. En tal caso se requiere de una nueva prueba. Para ello utilizamos el else if.

i <- 0.23
if(i < 0.22){
  print("Realizar el préstamo")
}else if (i < 0.24){
  print("Lo voy a pensar")
}
## [1] "Lo voy a pensar"

Else

Por último, si la tasa es \(\ge 24 \%\) definitivamente no se realiza el préstamo. En este caso el else es el complemento de las dos pruebas anteriores y no requiere ser evaluada explícitamente.

i <- 0.26
if(i < 0.22){
  print("Realizar el préstamo")
}else if(i < 0.24){
  print("Lo voy a pensar")
}else{
  print("No voy a realizar el préstamo")
}
## [1] "No voy a realizar el préstamo"

Observaciones

Una característica importante cuando se escribe una sentencia de decisión es que el programa ingresa a la primera prueba que es verdadera. Observemos detenidamente el siguiente código.

i <- 0.18
if(i < 0.26){
  print("No voy a realizar el préstamo")
}else if(i < 0.24){
  print("Lo voy a pensar")
}
## [1] "No voy a realizar el préstamo"

Como el interés (\(0.18\)) es menor a \(0.26\) la primera condición es verdadera y obtenemos como respuesta No voy a realizar el préstamo. El énfasis se debe a que generalmente se suele pensar que el programa se va preguntando cada una de las pruebas lógicas y esto no ocurre. :’(

Ciclos

Los ciclos nos permiten repetir un conjunto de instrucciones una “cierta” cantidad de veces. Nos enfocaremos principalmente en los ciclos for y while, repeat es uno que poco se usa en análisis de datos y se deja como consulta al investigador.

for

Esta estructura requiere de una variable que indexa una secuencia de números o de elementos un conjunto. Su sintaxis es la siguiente:

for ( variable in valores ) {
  Sentencia 1
  Sentencia N
}

Ejemplos

# Ejemplo 1

 for(i in 1:12){
   print(i)
 }
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
## [1] 11
## [1] 12
# Ejemplo 2

cto <- c("uno", "dos", "tres", 
     "cuatro","cinco", "seis",
     "siete", "ocho", "nueve")
for(k in cto){
  print(k)
} 
## [1] "uno"
## [1] "dos"
## [1] "tres"
## [1] "cuatro"
## [1] "cinco"
## [1] "seis"
## [1] "siete"
## [1] "ocho"
## [1] "nueve"

while

Este tipo de ciclo parte de una condición, en caso de que esta sea verdadera ejecuta las sentencias hasta que la prueba lógica se haga falsa.

Sintaxis

while(prueba lógica) {
  Sentencia 1
  Sentencia 2
  .
  .
  .
  Sentencia N
}

Código

cont <- 0
while(cont < 4){
  print(cont)
  cont <- cont + 1
}
## [1] 0
## [1] 1
## [1] 2
## [1] 3

Estos deben utilizarce con cuidado ya que si la prueba lógica no se hace falsa se corre con el riesgo de un bucle “infinito”.

Ejercicios prácticos.

La tasa interna de retorno, TIR, es uno de los indicadores más utilizados en finanzas ya que indica cual debe ser la tasa mínima a la que debe rentar una inversión con el fin de no generar pérdidas ni ganancias. La TIR está dada por la siguiente expresión:

\[TIR = \sum_{i = 1}^{n}\frac{F_{n}}{(1 + i)^n} - I_{0}= 0\]

La ecuación anterior se puede resolver análiticamente cuando \(n\) toma valores pequeños. Si \(n\) es grande, se recurre a métodos numéricos como bisección.

Bisección

Este método es utilizado para encontrar las raíces de \(f(x)\) asumiendo que la función es continua el intervalo \([a_{0}, a_{1}]\) y \(f(a_{0})*f(a_{1}) < 0\).

*** Diagrama de flujo del método de bisección.

Ejemplo

Vamos a determinar la \(TIR\) para el siguiente flujo de caja.

La ecuación que buscamos resolver es la siguiente: \[ TIR = \frac{200}{(1 + i) ^ 1} + \frac{150}{(1 + i) ^ 2} + \frac{350}{(1 + i)^3} + \frac{450}{(1 + i)^4} + \frac{300}{(1 + i)^5} - 1000 = 0\]

Ahora, para poder aplicar el método de bisección debemos garantizar que en un intervalo \([a, b]\) se cumpla que \(f(a)*f(b) < 0\) para que exista al menos una raíz.

La expresión anterior se puede resolver con el método de bisección obteniendo un resultado para \(i\) de: 0.1212383.

En la \(TIR\) tradicionalmente se asume que los periodos son iguales. En caso de que los periodos de pago sean diferentes se debe recurrir a la \(TirNoPer\) (la tir no periódica) dada por la siguiente expresión: \[\sum_{k = 1}^{n}\frac{F_{n}}{(1 + i)^\frac{d_{k}-d_{1}}{365}}= 0\]

El método funciona igual debido a que lo único que cambia es el exponente del denominador.

Determine la tir no periódica del siguiente flujo de caja.

Valores Fechas
-10000 1 ene 08
2750 1 mar 08
4250 30 oct 08
3250 15 feb 09
2750 1 abr 09


El resultado para la tir no periódica es 0.3733625. El ejemplo tomado de la ayuda de Excel

Simulación Montecarlo

El objetivo de esta técnica es aproximar una solución a un problema cuantitativo que abordarlo de forma análitica puede no ser muy práctico. Esto se logra a través de un muestreo estadístico.

Por ejemplo:

  • Mediante simulación calcule la probabilidad de que al menos dos personas de 38 cumplan años el mismo día. Para ello lea el archivo que se encuentra en cumple.csv y tome muestras de manera aleatoria de tamaño 38 y calcule la probabildiad.

Los siguientes ejercicios fueron tomados del curso de Optimización estocástica del programa doctorado en ingeniería dictado por el profesor John Fredy Franco Baquero el año 2022

  • Una recepcionista recibió \(N=10\) sombreros y decidió devolverlod de cualquier forma. Ecuentre la probababilidad de que ningún sombrero sea entregado a su dueño mediante simulación Montecarlo.

  • Usar simulación Monte Carlo para estimar la media de lanzamientos necesarios de seis dados, para que cada dado presente por lo menos una vez el valor de 6.

  • Estimar la distancia media entre dos puntos en un cuadrado de lado 1 usando simulaciones Montecarlo.

Una turbina eólica genera potencia eléctrica \(P\) en función de la velocidad del viento \(v\). Según las figuras:

Utilizar simulación montecarlo para determinar el valore esperado de la potencia si la velocidad sigue una distribución Weibull

La función de distribución de Weibull esta dada por:

\[f(v) = \left\{\begin{array}{ll} \frac{k}{\lambda}(\frac{v}{\lambda})^{k-1} e^{-(\frac{v}{\lambda})^k} & v \ge 0\\ 0 & v\le 0 \end{array} \right. \]

Para el ejercicio tomar un valor \(k = 2\) y \(\lambda=8\).

Algoritmo genético para solucionar el problema del agente viajero.

Referencias

Markowitz, Harry. 1952. “Porfolio Selection.” Journal of Finance 7.

Wickham, Hadley. 2010. GGplot2: Elegant Graphics for Data Analysis. Springer Science+Business Media.

———. 2015. Advanced r. CRC Press.

Wilkinson, Leland. 1999. The Grammar of Graphics. Springer.